﻿using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using ReadyApps.Data;
using ReadyApps.Wiki.Templates;
using ReadyApps.Wiki.ViewModels;

namespace ReadyApps.Wiki.Views
{
    class PageSettingsView : ViewBase
    {
        #region Variables and Constants

        private const string PUBLISHABLE_CHECKBOX_ID = "chkPublishable";
        private const string UNIT_CONTROL_ID = "ddlUnit";
        private const string MEASURE_CONTROL_ID = "txtMeasure";

        private const string SAVE_SETTINGS_VALIDATION_GROUP = "vgSaveSettings";
        private const string JAVASCRIPT_UPDATE_FUNCTION_NAME = "updateDisplay";

        private PageSettingsViewModel viewModel;

        private CheckBox chkPublishable;
        private TextBox txtMeasure;
        private DropDownList ddlUnit;

        #endregion

        #region Events

        private event EventHandler cancelButtonClick;
        public event EventHandler CancelButtonClick
        {
            add { cancelButtonClick += value; }
            remove { cancelButtonClick -= value; }
        }

        private event EventHandler<SaveViewModelEventArgs> saveButtonClick;
        public event EventHandler<SaveViewModelEventArgs> SaveButtonClick
        {
            add { saveButtonClick += value; }
            remove { saveButtonClick -= value; }
        }

        #endregion

        #region Constructor

        public PageSettingsView(WikiControlSettings wikiControlSettings, PageSettingsViewModel viewModel)
            : base(wikiControlSettings)
        {
            if (viewModel == null)
            {
                throw new ArgumentNullException("viewModel");
            }
            this.viewModel = viewModel;
        }

        #endregion

        #region Public Methods

        public override void BuildControlTree(ControlCollection controls, bool raiseEvents)
        {
            Control container = new Control();

            container.Controls.Add(new HtmlGenericControl("h1") { InnerText = "Page Settings" });

            if (viewModel.CanManagePublishing)
            {
                HtmlGenericControl publicationSettingsFieldSet = new HtmlGenericControl("fieldset");
                publicationSettingsFieldSet.Controls.Add(new HtmlGenericControl("legend") { InnerText = "Publication Settings" });
                chkPublishable = new CheckBox();
                chkPublishable.ID = PUBLISHABLE_CHECKBOX_ID;
                chkPublishable.Text = "Enable publishing workflow for this page";
                chkPublishable.Checked = viewModel.PublicationSettings.Publishable;
                publicationSettingsFieldSet.Controls.Add(chkPublishable);
                container.Controls.Add(publicationSettingsFieldSet);
            }

            if (viewModel.CanManageRevisions)
            {
                HtmlGenericControl retentionSettingsFieldSet = new HtmlGenericControl("fieldset");
                retentionSettingsFieldSet.Controls.Add(new HtmlGenericControl("legend") { InnerText = "Revision Settings" });

                HtmlGenericControl settingsParagraph = new HtmlGenericControl("p");
                settingsParagraph.Controls.Add(new Literal() { Text = "Retain page versions for " });
                txtMeasure = GetRetentionMeasureTextBox(viewModel.RetentionSettings.Measure, viewModel.RetentionSettings.Unit);
                settingsParagraph.Controls.Add(txtMeasure);
                ddlUnit = GetRetentionUnitDropDownList(viewModel.RetentionSettings.Unit);
                settingsParagraph.Controls.Add(ddlUnit);
                retentionSettingsFieldSet.Controls.Add(settingsParagraph);

                container.Controls.Add(retentionSettingsFieldSet);
            }

            WikiControlButton cancelButton = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
            cancelButton.ButtonControl.Text = "Cancel";
            cancelButton.ButtonControl.CausesValidation = false;
            cancelButton.ButtonControl.Click += cancelButtonClick;
            container.Controls.Add(cancelButton.RootControl);

            container.Controls.Add(new Literal() { Text = WikiController.BUTTON_SPACER });

            WikiControlButton saveButton = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
            saveButton.ButtonControl.Text = "Save";
            saveButton.ButtonControl.ValidationGroup = SAVE_SETTINGS_VALIDATION_GROUP;
            saveButton.ButtonControl.Click += new EventHandler(SaveButton_Click);
            container.Controls.Add(saveButton.RootControl);

            controls.Clear();
            controls.Add(container);

            if (raiseEvents)
            {
                // The ClientIDs are not set properly until added to the entire tree, so this call must be executed
                // after the controls have been added to the container.
                if (viewModel.CanManageRevisions)
                {
                    controlSettings.OnIncludeResource(this, new IncludeResourceEventArgs(IncludeType.ScriptBlock,
                        GetJavaScriptUpdateDisplayScript(txtMeasure.ClientID, ddlUnit.ClientID)));
                }
            }
        }

        #endregion

        #region Private Methods

        private void SaveButton_Click(object sender, EventArgs e)
        {
            if (saveButtonClick != null)
            {
                if (viewModel.CanManagePublishing)
                {
                    viewModel.PublicationSettings.Publishable = chkPublishable.Checked;
                }
                if (viewModel.CanManageRevisions)
                {
                    RetentionUnit unit = (RetentionUnit)Enum.Parse(typeof(RetentionUnit), ddlUnit.SelectedValue);
                    int measure = 0;
                    if (unit != RetentionUnit.None && unit != RetentionUnit.Forever)
                    {
                        measure = int.Parse(txtMeasure.Text);
                    }
                    viewModel.RetentionSettings.Unit = unit;
                    viewModel.RetentionSettings.Measure = measure;
                }
                saveButtonClick(this, new SaveViewModelEventArgs(viewModel));
            }
        }

        private DropDownList GetRetentionUnitDropDownList(RetentionUnit selectedUnit)
        {
            DropDownList ddlUnit = new DropDownList();
            ddlUnit.ID = UNIT_CONTROL_ID;
            foreach (var retentionUnit in Enum.GetNames(typeof(RetentionUnit)))
            {
                ddlUnit.Items.Add(retentionUnit);
            }
            ddlUnit.SelectedValue = selectedUnit.ToString();
            ddlUnit.Attributes.Add("onchange", JAVASCRIPT_UPDATE_FUNCTION_NAME + "();");
            return ddlUnit;
        }

        private TextBox GetRetentionMeasureTextBox(int selectedMeasure, RetentionUnit selectedUnit)
        {
            TextBox txtMeasure = new TextBox();
            txtMeasure.ID = MEASURE_CONTROL_ID;
            txtMeasure.Text = selectedMeasure.ToString();
            txtMeasure.Columns = 3;
            txtMeasure.MaxLength = 3;
            if (selectedUnit == RetentionUnit.None || selectedUnit == RetentionUnit.Forever)
            {
                txtMeasure.Style.Add(HtmlTextWriterStyle.Display, "None");
            }
            return txtMeasure;
        }

        private static string GetJavaScriptUpdateDisplayScript(string textboxClientID, string dropDownListClientID)
        {
            return string.Format(@"
function {0}() {{
    var ddl = document.getElementById('{1}');
    var txt = document.getElementById('{2}');
    if (ddl.value == '{3}' || ddl.value == '{4}') {{
        txt.style.display = 'None';
    }} else {{
        txt.style.display = '';
    }}
}}
",
                JAVASCRIPT_UPDATE_FUNCTION_NAME,
                dropDownListClientID,
                textboxClientID,
                RetentionUnit.None,
                RetentionUnit.Forever);
        }

        #endregion
    }
}
